home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
utility.lha
/
utility
/
list.H
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-08
|
8KB
|
214 lines
// This is a generic list package in C++. Any kind of object can be the
// member of such a list, but specialized list types are normally created for
// each type of object. An element can be the member of many lists at a time.
// Before an object is destructed, it must explicitly be taken out of any lists
// (otherwise there will be pointers left pointing to deallocated space).
//
// .SS Derived list types
// This is a protected class, i.e., it is not possible to create instances
// of it. Derived classes provide lists for specific types of objects.
// First, a new list type must be declared, for example, a list of integers:
//
// LIST_DECLARE(int);
// CONSTLIST_DECLARE(int);
//
// This declares a new class, called `intList', and a list of "const int".
// List types should only be declared once, even if there are many lists.
// After that, lists of this type can be declared as needed:
//
// LIST(int) l1, l2;
// CONSTLIST(int) cl1;
//
// In every case where `Pointer' is a parameter in class GenericList, the
// derived list types will accept either an object (int, above) or a
// pointer to an object (int *, above).
//
// The function
//
// LIST_DELETE(l,int);
//
// will delete all (integer) elements of the list `l', but not the list itself.
// The elements had better be allocated on the free-store.
//
// .SS Performance
// The list is implemented as an array of pointers.
// Inserting elements at the front of the list (Insert() and operator +=)
// is cheap; removing elements (except the first) and inserting at the end
// is more expensive. Assignment and passing a list as a VALUE parameter
// requires copying of the pointer array, and is therefore expensive; pass
// lists as "const reference" parameters instead.
//
// .SS History
// Author: Dag Bruck
//
// $Id: list.H,v 1.2 91/03/03 22:08:14 dag Exp $
#ifndef LIST_H
#define LIST_H
#include <defs.H>
typedef void* Pointer;
class GenericList {
friend class GenericIterator;
public:
GenericList();
// Constructs a list with no elements.
~GenericList();
// Destroys the list. The elements in the list are not
// destroyed. LIST_DELETE(list,type) will delete all
// elements of the list.
void Insert(Pointer);
void operator += (Pointer);
// Inserts an element first in list.
void Append(Pointer);
// Inserts an element last in list. Not as efficient as Insert().
void Append(const GenericList &);
// Appends another list to this list.
void Remove(Pointer);
// Removes an element from the list. The element is not destroyed.
// It is o.k. to remove an element which is not a member of the list.
void RemoveAll();
// Removes all elements from the list. The elements are not destroyed.
boolean Member(Pointer) const;
// Returns true if the element is a member of list.
void Replace(Pointer p, Pointer q);
// Replaces every occurence of "p" with "q".
void Reverse();
// Reverses the order of the elements in the list. The list is reversed
// in place, i.e., the original order is lost.
Pointer First() const;
// Returns the first element of list, or nil if list is empty.
Pointer Second() const;
// Returns the second element of list, or nil if < 2 elements exist.
Pointer Third() const;
// Returns the third element of list, or nil if < 3 elements exist.
Pointer Fourth() const;
// Returns the fourth element of list, or nil if < 4 elements exist.
Pointer Fifth() const;
// Returns the fifth element of list, or nil if < 5 elements exist.
Pointer Nth(const int) const;
// Returns the i:th element of list, or nil if < i elements exist.
Pointer Last() const;
// Returns the last element of list, or nil if list is empty.
unsigned Length() const;
// Returns the number of elements in list.
boolean Empty() const;
// Returns true if list is empty.
GenericList(const GenericList&);
// Used for passing parameters and return values.
void operator = (const GenericList&);
// Assignment.
private:
Pointer* p;
// Array of pointers to actual member objects.
unsigned n;
// Number of elements in list.
unsigned size;
// Maximum number of elements in list.
void Expand();
// Expand array of pointers to cope with more elements.
};
inline void GenericList :: operator += (Pointer e)
{ Insert(e); }
inline unsigned GenericList :: Length() const
{ return n; }
inline boolean GenericList :: Empty() const
{ return n == 0; }
#define LIST_DELETE(list,type) while (!(list).Empty()) \
{ type* p = (list).First(); (list).Remove(p); delete p; }
#define LIST(type)NAME2(type,List)
#define CONSTLIST(type)NAME2(NAME2(const_,type),List)
#define LIST_DECLARE(type)LIST_DECLARE2(LIST(type),type)
#define CONSTLIST_DECLARE(type)CONSTLIST_DECLARE2(CONSTLIST(type),type)
/* To make lists of nested classes we need some way to give full type */
#define LIST_DECLARE2(__name,type) class __name : public GenericList { \
public: \
__name() {} \
~__name() {} \
void Insert(type* x) { GenericList::Insert(x); } \
void Insert(type& x) { GenericList::Insert(&x); } \
void operator += (type* x) { GenericList::operator += (x); } \
void operator += (type& x) { GenericList::operator += (&x); } \
void Append(type* x) { GenericList::Append(x); } \
void Append(type& x) { GenericList::Append(&x); } \
void Append(const LIST(type)& x) { GenericList::Append(x); } \
void Remove(type* x) { GenericList::Remove(x); } \
void Remove(type& x) { GenericList::Remove(&x); } \
boolean Member(type* x) const { return GenericList::Member(x); } \
boolean Member(type& x) const { return GenericList::Member(&x); } \
void Replace(type* p, type* q) { GenericList::Replace(p, q); } \
void Replace(type& p, type& q) { GenericList::Replace(&p, &q); } \
type* First() const { return (type *) GenericList::First(); } \
type* Second() const { return (type *) GenericList::Second(); } \
type* Third() const { return (type *) GenericList::Third(); } \
type* Fourth() const { return (type *) GenericList::Fourth(); } \
type* Fifth() const { return (type *) GenericList::Fifth(); } \
type* Nth(const int i) const { return (type *) GenericList::Nth(i); } \
type* Last() const { return (type *) GenericList::Last(); } \
}
#define CONSTLIST_DECLARE2(__name,type) class __name : public GenericList { \
public: \
__name() {} \
__name(const LIST(type)& l) : GenericList(l) {} \
~__name() {} \
void Insert(const type* x) { GenericList::Insert((type *) x); } \
void Insert(const type& x) { GenericList::Insert((type *) &x); } \
void operator += (const type* x) { GenericList::operator += ((type*)x); } \
void operator += (const type& x) { GenericList::operator += ((type*)&x); } \
void Append(const type* x) { GenericList::Append((type*)x); } \
void Append(const type& x) { GenericList::Append((type*)&x); } \
void Append(const CONSTLIST(type)& x) { GenericList::Append((LIST(type)&)x); } \
void Remove(const type* x) { GenericList::Remove((type*)x); } \
void Remove(const type& x) { GenericList::Remove((type*)&x); } \
boolean Member(const type* x) const { return GenericList::Member((type*)x); } \
boolean Member(const type& x) const { return GenericList::Member((type*)&x); } \
void Replace(const type* p, const type* q) { GenericList::Replace((type*)p, (type*)q); } \
void Replace(const type& p, const type& q) { GenericList::Replace((type*)&p, (type*)&q); } \
const type* First() const { return (const type *) GenericList::First(); } \
const type* Second() const { return (const type *) GenericList::Second(); } \
const type* Third() const { return (const type *) GenericList::Third(); } \
const type* Fourth() const { return (const type *) GenericList::Fourth(); } \
const type* Fifth() const { return (const type *) GenericList::Fifth(); } \
const type* Nth(const int i) const { return (const type *) GenericList::Nth(i); } \
const type* Last() const { return (const type *) GenericList::Last(); } \
}
#endif